//
//  ApiCenter.m
//  Dermvpure
//
//  Created by <北京>杨硕 on 4/6/16.
//  Copyright © 2016 Dermvpure. All rights reserved.
//
#import "ApiCenter.h"

#import "AFNetworking.h"
#import "AFNetworkActivityIndicatorManager.h"
#import "MJExtension.h"
#import "ZTMacros.h"

//#import "AppDelegate.h"


//#import "FileModel.h"

@interface ApiCenter ()
@property(nonatomic, strong) NSMutableSet *requests;
@property(nonatomic, strong) AFHTTPSessionManager *requestManager;
@end

@implementation ApiCenter

static ApiCenter *apiCenter = nil;

+ (ApiCenter *)defaultClient
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        apiCenter = [[ApiCenter alloc] init];
    });
    return apiCenter;
}


- (instancetype)init {
    DCHECK([NSThread isMainThread]);
    
    self = [super init];
    if (self) {
        [[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
        [AFNetworkActivityIndicatorManager sharedManager].activationDelay = 0;
        _requests = [NSMutableSet set];
        
        NSURLSessionConfiguration *configuration =
        [NSURLSessionConfiguration defaultSessionConfiguration];
        configuration.timeoutIntervalForRequest = 50;//请求时间15
        
        _requestManager = [[AFHTTPSessionManager manager] initWithSessionConfiguration:configuration];
        
        //      AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
        //      //allowInvalidCertificates 是否允许无效证书（也就是自建的证书），默认为NO//如果是需要验证自建证书，需要设置为YES
        //      securityPolicy.allowInvalidCertificates = YES;
        //      //validatesDomainName 是否需要验证域名，默认为YES；
        //      securityPolicy.validatesDomainName = NO;
        //      _requestManager.securityPolicy  = securityPolicy;
        //      [_requestManager setSecurityPolicy:[self customSecurityPolicy]];
        
        _requestManager.requestSerializer = [AFHTTPRequestSerializer serializer];
        _requestManager.responseSerializer = [AFJSONResponseSerializer serializer];
        _requestManager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html", @"text/json", @"text/javascript",@"text/plain", nil];
        
        // 在线程池中执行
        _requestManager.completionQueue =
        dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        
    }
    return self;
}

- (NSURLSessionDataTask *)request:(BaseRequest *)request
                      reponseType:(Class)type
                          success:(ApiCenterSuccessBlock)success
                          failure:(ApiCenterFailureBlock)failure {
    DCHECK([NSThread isMainThread]);
    DCHECK(success);
    DCHECK(failure);
    DLog("%@", [request url]);
   
    
    @weakify(self);
    void (^successBlock)(NSURLSessionDataTask *task, id responseObject) =
    ^(NSURLSessionDataTask *task, id responseObject) {
        @strongify(self);
        DCHECK(![NSThread isMainThread]);
        [[AFNetworkActivityIndicatorManager sharedManager] decrementActivityCount];
        
        BaseModel *model = [type mj_objectWithKeyValues:responseObject];
        
        @weakify(self);
        dispatch_async(dispatch_get_main_queue(), ^{
            @strongify(self);
            if (!self) {
                return;
            }
            if (![self.requests containsObject:task]) {
                return;
            }
            
            if ([model.result isEqualToString:@"fail"] || [model.result isEqualToString:@"error"]) {
                ErrorModel *error = [[ErrorModel alloc] init];
                error.message = model.errmsg;
                error.errcode = [model.errcode integerValue];
                error.msg = model.msg;
                failure(error);
                return ;
            }
            
            [self.requests removeObject:task];
            model.request = task;
            success(model);
        });
    };
    void (^failureBlock)(NSURLSessionDataTask *task, NSError *error) =
    ^(NSURLSessionDataTask *task, NSError *error) {
        @strongify(self);
        DCHECK(![NSThread isMainThread]);
        
        NSLog(@"error: %@",error);
        
        [[AFNetworkActivityIndicatorManager sharedManager] decrementActivityCount];
        
        ErrorModel *errorModel;
        NSData *errorData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
        if (errorData != nil) {
            NSLog(@"出错了哦~:%@",errorData);
            NSString *errorString = [[NSString alloc] initWithData:errorData
                                                          encoding:NSUTF8StringEncoding];
            errorModel = [ErrorModel mj_objectWithKeyValues:errorString];
        }
        
        if (!errorModel) {
            errorModel = [[ErrorModel alloc] init];
            errorModel.errcode = error.code;
            errorModel.message = error.localizedDescription;
        }
        if ([errorModel.message containsString:@"未能读取数据"]) {
            errorModel.message = @"无法连接到服务器";
        }
        
        DLog(@"%@", errorModel);
        
        @weakify(self);
        dispatch_async(dispatch_get_main_queue(), ^{
            @strongify(self);
            if (!self) {
                return;
            }
            NSHTTPURLResponse* response = (NSHTTPURLResponse *)task.response;
            if (response.statusCode == 401) {
                
            }
            if (![self.requests containsObject:task]) {
                return;
            }
            
            [self.requests removeObject:task];
            failure(errorModel);
        });
    };
    
    NSURLSessionDataTask *task;
    
    switch ([request method]) {
        case ZTHttpMethodGet:
            task = [self.requestManager GET:[request url] parameters:[request params] headers:nil progress:nil success:successBlock failure:failureBlock];
            break;
        case ZTHttpMethodPost:
            task = [self.requestManager POST:[request url] parameters:[request params] headers:nil progress:nil success:successBlock failure:failureBlock];
            break;
        case ZTHttpMethodDelete:
//            task = [self.requestManager DELETE:[request url]
//                                    parameters:[request params]
//                                       success:successBlock
//                                       failure:failureBlock];
            break;
        case ZTHttpMethodPut:
//            task = [self.requestManager PUT:[request url]
//                                 parameters:[request params]
//                                    success:successBlock
//                                    failure:failureBlock];
            break;
        default:
            NOTREACHED();
    }
    
    
    [[AFNetworkActivityIndicatorManager sharedManager] incrementActivityCount];
    
    [self.requests addObject:task];
    return task;
}


#pragma mark -- POST请求 --
- (void)postWithURLString:(NSString *)URLString
               parameters:(id)parameters
                  success:(void (^)(BaseModel *))success
                  failure:(void (^)(NSError *))failure {
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
//    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    manager.responseSerializer.acceptableContentTypes =[NSSet setWithObjects:@"text/plain",@"application/json",@"text/json",@"text/javascript",@"text/html", nil];

    
    [manager POST:URLString parameters:parameters headers:nil progress:^(NSProgress * _Nonnull uploadProgress) {
        
        
        
    }success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//        NSString *string = [[NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding];
        
        
        NSString *str = [[NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding];
        DLog(@"%@",str);
        
        if (success) {
            BaseModel *model = [BaseModel mj_objectWithKeyValues:responseObject];
            success(model);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (failure) {
//            NSData *errorData = error.userInfo[AFNetworkingOperationFailingURLResponseDataErrorKey];
//            
//            NSString *errorString = [[NSString alloc] initWithData:errorData
//                                                          encoding:NSUTF8StringEncoding];
//            ErrorModel *errorModel = [ErrorModel mj_objectWithKeyValues:errorString];
//
            
            failure(error);
        }
    }];
}

- (void)postEmengencyOfficeWithURLString:(NSString *)URLString
                              parameters:(id)parameters
                                 success:(void (^)(NSArray* arr))array
                                 failure:(void (^)(NSError * err))failure {
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    [manager POST:URLString parameters:parameters headers:nil progress:^(NSProgress * _Nonnull uploadProgress) {
        
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSString *string = [[NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding];
        if (array) {
            //            NSArray *arr = [VEmergencyOfficeModel mj_objectArrayWithKeyValuesArray:string[@"msg"][@"dateList"]];
            //            array(arr);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (failure) {
            failure(error);
        }
    }];
}

- (void)postEmengencyPersonWithURLString:(NSString *)URLString
                              parameters:(id)parameters
                                 success:(void (^)(NSArray* arr))array
                                 failure:(void (^)(NSError * err))failure {
    
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    [manager POST:URLString parameters:nil headers:nil progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSString *string = [[NSString alloc]initWithData:responseObject encoding:NSUTF8StringEncoding];
        if (array) {
//            NSArray *arr = [VEmergencyPersonModel
//                            mj_objectArrayWithKeyValuesArray:string];
//            array(arr);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (failure) {
            failure(error);
        }
    }];
}



/**
 *  上传图片
 */
- (void)uploadImageWithUrl:(NSString *)url params:(NSDictionary *)params image:(UIImage *)image uploadProgress:(void (^)(NSProgress * uploadProgress))upload success:(ApiCenterSuccessBlock)success failure:(ApiCenterFailureBlock)failure
{
    self.requestManager.requestSerializer = [AFJSONRequestSerializer serializer];
    // 2.发送请求
//    [self.requestManager POST:[NSString stringWithFormat:@"http://101.201.108.172:8280/masCustomer/service/%@",url] parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
//        NSDate *date = [NSDate date];
//        NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
//        [formatter setDateFormat:@"yyyyMMddHHmmss"];
//        NSString *dateString = [formatter stringFromDate:date];
//
//        NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
//        NSString *fileName = [NSString stringWithFormat:@"%@.png",dateString];
//        // 上传图片
//        [formData appendPartWithFileData:imageData name:@"file" fileName:fileName mimeType:@"image/jpg/png/jpeg"];
//    } progress:^(NSProgress * _Nonnull uploadProgress) {
//        if (upload) {
//            upload(uploadProgress);
//        }
//    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//        if (success) {
//            BaseModel *model = [BaseModel mj_objectWithKeyValues:responseObject];
//            success(model);
//        }
//    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//        // 失败
//        NSLog(@"Error: %@", error);
//        if (failure) {
//            ErrorModel *errorModel = [[ErrorModel alloc] init];
//            errorModel.errcode = error.code;
//            errorModel.message = error.localizedDescription;
//            failure(errorModel);
//        }
//    }];
    
}

/**
 *  上传附件
 */
- (void)uploadFileWithUrl:(NSString *)url params:(NSDictionary *)params Filedata:(NSMutableArray *)fileDataArray uploadProgress:(void (^)(NSProgress * uploadProgress))upload success:(ApiCenterSuccessBlock)success failure:(ApiCenterFailureBlock)failure{
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",@"text/plain", nil];
    //向请求头中添加参数
    [manager.requestSerializer setValue:[kUserDefaults objectForKey:APPDeviceToken] forHTTPHeaderField:@"token"];
 
//    NSURLSessionDataTask *uploadTask = [manager POST:url parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
//
//        if (fileDataArray.count) {
//            for (id object in fileDataArray) {
////                if ([object isKindOfClass:[UIImage class]]) {
////                    //图片
////                    NSDate *date = [NSDate date];
////                    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
////                    [formatter setDateFormat:@"yyyyMMddHHmmssSSS"];
////                    NSString *dateString = [formatter stringFromDate:date];
////                    NSData *data = [[NSData alloc]init];
////                    dateString = [NSString stringWithFormat:@"%@.png",dateString];
////
////                    data = UIImageJPEGRepresentation(object, .9);
////
////                    if (data.length == 0) {
////                        ErrorModel *errorModel = [[ErrorModel alloc] init];
////                        errorModel.message = @"文件太大，上传异常";
////                        failure(errorModel);
////                        return ;
////                    }
////                    //将得到的二进制数据拼接到表单中 /** data,指定上传的二进制流;name,服务器端所需参数名*/
////                    [formData appendPartWithFileData:data name:@"file" fileName:dateString mimeType:@"image/jpeg"];
////                }else if ([object isKindOfClass:[FileModel class]]){
////                    //附件
////                    //                NSArray *array = @[@"document",
////                    //                                   @"music",
////                    //                                   @"pdf",
////                    //                                   @"ppt",
////                    //                                   @"video",
////                    //                                   @"xls",
////                    //                                   @"picture",
////                    //                                   @"other"];
////                    FileModel *model = (FileModel *)object;
////                    NSString *name = [NSString stringWithFormat:@"%@",model.fileName];
////                    NSFileManager *fileManager = [NSFileManager defaultManager];
////                    NSData *data = [fileManager contentsAtPath:model.filePath];
////                    //将得到的二进制数据拼接到表单中 /** data,指定上传的二进制流;name,服务器端所需参数名*/
////                    [formData appendPartWithFileData:data name:@"file" fileName:name mimeType:@"application/octet-stream"];
////
////                }else{
////                    //语音
////                    NSDate *date = [NSDate date];
////                    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
////                    [formatter setDateFormat:@"yyyyMMddHHmmssSSS"];
////                    NSString *dateString = [formatter stringFromDate:date];
////                    NSString *name = [NSString stringWithFormat:@"%@.amr",dateString];
////
////                    [formData appendPartWithFileData:object name:@"file" fileName:name mimeType:@"application/octet-stream"];
////                }
//            }
//        }
//
//        //进度
////          progress(uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
// } progress:^(NSProgress * _Nonnull uploadProgress) {
//
//     NSLog(@"上传进度--%lld, 总进度---%lld",uploadProgress.completedUnitCount,uploadProgress.totalUnitCount);
//
//     /*! 回到主线程刷新UI */
////     dispatch_async(dispatch_get_main_queue(), ^{
////         if (progressBlock)
////         {
////             progressBlock(uploadProgress.completedUnitCount, uploadProgress.totalUnitCount);
////         }
////     });
//
// } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
//     BaseModel *model = [BaseModel mj_objectWithKeyValues:responseObject];
//        if (success && [model.result isEqualToString:@"success"]) {//成功
//            success(responseObject);
//        }
//
//    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//        if (failure) {
//            ErrorModel *errorModel = [[ErrorModel alloc] init];
//            errorModel.errcode = error.code;
//            errorModel.message = error.localizedDescription;
//            failure(errorModel);
//        }
//    }];
//    [uploadTask resume];
    
}
- (NSString *)mainPath{
    
//    NSArray *pathes = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    //
//    NSString *docDir =  [NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory,   NSUserDomainMask, YES) objectAtIndex:0];//[pathes objectAtIndex:0];
//    return [docDir stringByAppendingPathComponent:[NSString stringWithFormat:@"/HyphenateSDK/appdata/%@/",[[LoginUserService defaultService] getLoginUserAccount]]];
    return @"";
}






- (AFSecurityPolicy*)customSecurityPolicy {
    // /先导入证书
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"inch.tsminfo.com" ofType:@"cer"];//证书的路径
    NSData *certData = [NSData dataWithContentsOfFile:cerPath];
    
    // AFSSLPinningModeCertificate 使用证书验证模式
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
    
    // allowInvalidCertificates 是否允许无效证书（也就是自建的证书），默认为NO
    // 如果是需要验证自建证书，需要设置为YES
    securityPolicy.allowInvalidCertificates = YES;
    
    //validatesDomainName 是否需要验证域名，默认为YES；
    //假如证书的域名与你请求的域名不一致，需把该项设置为NO；如设成NO的话，即服务器使用其他可信任机构颁发的证书，也可以建立连接，这个非常危险，建议打开。
    //置为NO，主要用于这种情况：客户端请求的是子域名，而证书上的是另外一个域名。因为SSL证书上的域名是独立的，假如证书上注册的域名是www.google.com，那么mail.google.com是无法验证通过的；当然，有钱可以注册通配符的域名*.google.com，但这个还是比较贵的。
    //如置为NO，建议自己添加对应域名的校验逻辑。
    securityPolicy.validatesDomainName = NO;
    
    securityPolicy.pinnedCertificates = [NSSet setWithObject:certData];
    
    return securityPolicy;
}

- (void)cancel:(NSObject *)task {
    DCHECK([NSThread isMainThread]);
    
    if ([self.requests containsObject:task]) {
        [self.requests removeObject:task];
        [(NSURLSessionDataTask *)task cancel];
    }
}


@end
